#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
+/*
+ * Module parameter 'queue_length':
+ *
+ * Enables queuing in the network stack when a client has run out of receive
+ * descriptors. Although this feature can improve receive bandwidth by avoiding
+ * packet loss, it can also result in packets sitting in the 'tx_queue' for
+ * unbounded time. This is bad if those packets hold onto foreign resources.
+ * For example, consider a packet that holds onto resources belonging to the
+ * guest for which it is queued (e.g., packet received on vif1.0, destined for
+ * vif1.1 which is not activated in the guest): in this situation the guest
+ * will never be destroyed, unless vif1.1 is taken down (which flushes the
+ * 'tx_queue').
+ *
+ * Only set this parameter to non-zero value if you know what you are doing!
+ */
+static unsigned long netbk_queue_length = 0;
+module_param_named(queue_length, netbk_queue_length, ulong, 0);
+
static void __netif_up(netif_t *netif)
{
enable_irq(netif->irq);
SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
- /*
- * Reduce default TX queuelen so that each guest interface only
- * allows it to eat around 6.4MB of host memory.
- */
- dev->tx_queue_len = 100;
+ dev->tx_queue_len = netbk_queue_length;
+ if (dev->tx_queue_len != 0)
+ printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
+ "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
for (i = 0; i < ETH_ALEN; i++)
if (be_mac[i] != 0)
be->netif->remaining_credit = be->netif->credit_bytes;
xenbus_switch_state(dev, XenbusStateConnected);
+
+ /* May not get a kick from the frontend, so start the tx_queue now. */
+ if (!netbk_can_queue(be->netif->dev))
+ netif_start_queue(be->netif->dev);
}
}
be->netif->copying_receiver = !!rx_copy;
- if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-notify", "%d",
- &val) < 0)
- val = 0;
- if (val)
- be->netif->can_queue = 1;
- else
- /* Must be non-zero for pfifo_fast to work. */
- be->netif->dev->tx_queue_len = 1;
+ if (be->netif->dev->tx_queue_len != 0) {
+ if (xenbus_scanf(XBT_NIL, dev->otherend,
+ "feature-rx-notify", "%d", &val) < 0)
+ val = 0;
+ if (val)
+ be->netif->can_queue = 1;
+ else
+ /* Must be non-zero for pfifo_fast to work. */
+ be->netif->dev->tx_queue_len = 1;
+ }
if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-sg", "%d", &val) < 0)
val = 0;